
//#include <Xm/XmAll.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#ifndef WIN32
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#endif
#include<signal.h>
#include <fcntl.h>
#include <sys/types.h>

#include "rdb_lib.h"
#include "CList.h"
#include "usleep.h"
#include "CalSubDef.h"

#define	FREQUENCE_SINGLE	0
#define	FREQUENCE_MUTI		1
int   timer = 0;

typedef	struct	_TimerDo
{
	struct timer_info_scada		timer_struct;
	int				interval_time;
	int				do_mark;
//	void	Remove()		{delete	this;};
}	TimerDo;

CList<TimerDo>		TimerDoList;
int			CurMachineID;

void	GetTimerInfo()
{
	int		i;
	int 		nRetcode;
	TableOp		TmpTableOp;
	short 		field_num;
	int 		rec_num,rec_size,buf_size,counter;
	char		*buffer;
	time_t		tmptime;
	TimerDo		*pTimerDo;
	struct timer_info_scada		TimerInfoStruct;

	nRetcode = TmpTableOp.TableOpen(PUBLIC,TIMER_INFO_NO);
	if (nRetcode < 0) 
	{
	       	printf("Error: ---TableOpen error !---- \n");
		return;
	}

		
	TmpTableOp.GetTablePara(field_num,rec_num,rec_size);
	if	(rec_num==0)	
		return;
	buf_size=rec_num*rec_size;
	buffer=(char *)malloc(buf_size);
	TmpTableOp.TableGet(buffer, buf_size);


	if	(TimerDoList.GoHead())
		TimerDoList.DeleteAllNext();		
		
	time(&tmptime);
	counter=0;
	for	(i=0;i<rec_num;i++)
	{		
		memcpy(&TimerInfoStruct,buffer+counter,sizeof(struct timer_info_scada));
		if	(TimerInfoStruct.machine_id==CurMachineID)
		{
			pTimerDo=new	TimerDo;
			memcpy(&pTimerDo->timer_struct,buffer+counter,sizeof(struct timer_info_scada));
			if	(pTimerDo->timer_struct.frequence==FREQUENCE_MUTI)
			{
				switch	(pTimerDo->timer_struct.interval_type)
				{
					case	0:
						pTimerDo->interval_time=pTimerDo->timer_struct.time_interval*60;
						break;
					case	1:
						pTimerDo->interval_time=pTimerDo->timer_struct.time_interval*60*60;
						break;
					case	2:
						pTimerDo->interval_time=pTimerDo->timer_struct.time_interval*60*60*24;
						break;
				}
				if	(tmptime<pTimerDo->timer_struct.occur_time)
					pTimerDo->do_mark=-1;
				else
					pTimerDo->do_mark=(tmptime-pTimerDo->timer_struct.occur_time)/pTimerDo->interval_time;
			}
			else if	(pTimerDo->timer_struct.frequence==FREQUENCE_SINGLE)
			{
				pTimerDo->interval_time=-1;
				pTimerDo->do_mark=0;	
				if	(tmptime>pTimerDo->timer_struct.occur_time)
					pTimerDo->do_mark=-1;	
			}
			TimerDoList.Append(pTimerDo);
		}
		counter+=sizeof(struct timer_info_scada);
	}
	free(buffer);

	nRetcode = TmpTableOp.TableClose();
	if	(nRetcode < 0) 
	{
	        printf("Error: ---TableClose error !---- \n");
		return;
	}	
}

void	GetTimerInfoCmp()
{
	int		i;
	int 		nRetcode;
	TableOp		TmpTableOp;
	short 		field_num;
	int 		rec_num,rec_size,buf_size,counter;
	char		*buffer;
	struct timer_info_scada		*TimerStructPtr;
	int		tmpcount,j;
	TimerDo		*pTimerDo;
	time_t		tmptime;
	

	nRetcode = TmpTableOp.TableOpen(PUBLIC,TIMER_INFO_NO);
	if (nRetcode < 0) 
	{
	       	printf("Error: ---TableOpen error !---- \n");
		return;
	}

		
	TmpTableOp.GetTablePara(field_num,rec_num,rec_size);
	if	(rec_num==0){
		if	(TimerDoList.GoHead())
			TimerDoList.DeleteAllNext();		
		return;
	}
	buf_size=rec_num*rec_size;
	buffer=(char *)malloc(buf_size);
	TmpTableOp.TableGet(buffer, buf_size);
	TimerStructPtr=(struct timer_info_scada	*)buffer;
	
	time(&tmptime);
	tmpcount=TimerDoList.Count();
	j=0;
	if	(TimerDoList.GoHead())
	{
		while	(1)
		{
			pTimerDo=TimerDoList.Object();
			for	(i=0;i<rec_num;i++)
			{
				if	(CurMachineID!=TimerStructPtr[i].machine_id)
					continue;
				if	((pTimerDo->timer_struct.occur_time == TimerStructPtr[i].occur_time) &&
					!strcmp(pTimerDo->timer_struct.occur_event,TimerStructPtr[i].occur_event) &&
					(pTimerDo->timer_struct.frequence == TimerStructPtr[i].frequence) &&
					(pTimerDo->timer_struct.time_interval == TimerStructPtr[i].time_interval) &&
					(pTimerDo->timer_struct.interval_type == TimerStructPtr[i].interval_type))
				{
					TimerStructPtr[i].machine_id=-1;
					break;
				}
			}
			if	(i<rec_num)
				TimerDoList.GoNext();
			else
				TimerDoList.Delete();
			j++;
			if	(j==tmpcount)
				break;
		}
	}
	for	(i=0;i<rec_num;i++)
	{
		if	(TimerStructPtr[i].machine_id==-1 || TimerStructPtr[i].machine_id!=CurMachineID)
			continue;
		pTimerDo=new	TimerDo;
		memcpy(&pTimerDo->timer_struct,&TimerStructPtr[i],sizeof(struct timer_info_scada));
		if	(pTimerDo->timer_struct.frequence==FREQUENCE_MUTI)
		{
			switch	(pTimerDo->timer_struct.interval_type)
			{
				case	0:
					pTimerDo->interval_time=pTimerDo->timer_struct.time_interval*60;
					break;
				case	1:
					pTimerDo->interval_time=pTimerDo->timer_struct.time_interval*60*60;
					break;
				case	2:
					pTimerDo->interval_time=pTimerDo->timer_struct.time_interval*60*60*24;
					break;
			}
			if	(tmptime<pTimerDo->timer_struct.occur_time)
				pTimerDo->do_mark=-1;
			else
				pTimerDo->do_mark=(tmptime-pTimerDo->timer_struct.occur_time)/pTimerDo->interval_time;
		}
		else if	(pTimerDo->timer_struct.frequence==FREQUENCE_SINGLE)
		{
			pTimerDo->interval_time=-1;
			pTimerDo->do_mark=0;	
			if	(tmptime>pTimerDo->timer_struct.occur_time)
				pTimerDo->do_mark=-1;	
		}
		TimerDoList.Append(pTimerDo);
	}
	free(buffer);

	nRetcode = TmpTableOp.TableClose();
	if	(nRetcode < 0) 
	{
	        printf("Error: ---TableClose error !---- \n");
		return;
	}
}

void	DoThing(char	*event1)
{
	int len = strlen(event1);
	if(len <= 0) return;

	char *cmd = (char*)malloc(len+2);
	strcpy(cmd, event1);
	if(cmd[len-1] != '&')
	{
		strcat(cmd, "&");
	}
	printf("%s\n",cmd);
#ifndef WIN32
	system(cmd);
#else
	STARTUPINFO si = { sizeof(si) };
	PROCESS_INFORMATION pi;
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = TRUE;
	char pathname[256];
	ns_get_bin_dir(pathname, 256);
	printf("path==%s\n",pathname);
	BOOL bRet = CreateProcess (NULL,cmd,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,pathname,&si,&pi);
	printf("ret==%d\n",bRet);
     if (bRet)
	 {
		CloseHandle(pi.hThread);
		CloseHandle(pi.hProcess);
    }
#endif
	free(cmd);
/*	int	pid;
	
	pid=fork();
	if (pid==0)
	{
		system(event);
		exit(0);
	}
*/	
}

int	GetMachineID()
{
	int				tmpsize;
	char				*tmpbuf;
	struct machine_info_scada*	NodeInfoPtr;
	int				NodeInfoNum,i;
	char				HostName[40];
	
	
	tmpsize = 8;
	tmpbuf = (char* )malloc(tmpsize);
	NodeInfoNum = GetAllRec(PUBLIC, MACHINE_INFO_NO, tmpbuf, tmpsize);
	NodeInfoPtr = (machine_info_scada* )tmpbuf;
	ns_gethostname(HostName, 40);
    	for	(i=0;i<NodeInfoNum;i++)
    	{
    		if	(strcmp(HostName,NodeInfoPtr[i].machine_name)==0)
    		{
    			CurMachineID=NodeInfoPtr[i].machine_id;
    			break;
    		}
    	}
    	free(tmpbuf);
	return	0;		
}

void CTimer()
{
	int		tmpmark;
	time_t		tmptime;
	TimerDo		*pTimerDo;
	char		tmpbuf[100];
	struct	tm	tmstruct;
	int		pid;
//	int		fd;
	char		*p;

	OdbApiVarInit();
	InitApp(PUBLIC);

	
/*	sigset(SIGALRM,do_nothing);
	sigset(SIGTERM,do_nothing);
	sigset(SIGKILL,do_nothing);
	sigset(SIGINT,do_nothing);
	sigset(SIGHUP,do_nothing);*/
	
	
	GetMachineID();
	GetTimerInfo();
	if(TimerDoList.Count()==0)
		return;
	timer++;
	time(&tmptime);
	localtime_r(&tmptime,&tmstruct);
	p=asctime(&tmstruct);
	sprintf(tmpbuf,"%s",p);
	if	(timer%300==0)
	{
		GetTimerInfoCmp();
		timer=0;
	}
	if	(TimerDoList.GoHead())
	{
		do
		{
			pTimerDo=TimerDoList.Object();
			printf("time = %d,do_mark = %d\n",pTimerDo->interval_time,pTimerDo->do_mark);
			if	(pTimerDo->interval_time<0)
			{
				if	(pTimerDo->do_mark==0)
				{
					if	(tmptime>=pTimerDo->timer_struct.occur_time)
					{
						printf("1111  %s --- %s \n ",tmpbuf,pTimerDo->timer_struct.occur_event);
						DoThing(pTimerDo->timer_struct.occur_event);
						pTimerDo->do_mark=-1;
					}
				}
			}
			else
			{
				if	(tmptime<pTimerDo->timer_struct.occur_time)
					tmpmark=-1;
				else
					tmpmark=(tmptime-pTimerDo->timer_struct.occur_time)/pTimerDo->interval_time;
				if	(tmpmark>=0 && tmpmark>pTimerDo->do_mark)
				{
					printf("22222 %s --- %s  \n ",tmpbuf,pTimerDo->timer_struct.occur_event);
					DoThing(pTimerDo->timer_struct.occur_event);
					pTimerDo->do_mark=tmpmark;
				}	
			}
		} while(TimerDoList.GoNext());
	}		
	ShutDownApp(PUBLIC);
}
